header {
package com.aote.expression.antlr;
import com.browsesoft.htmlcomponent.HTMLBasicComponent;
import com.aote.expression.ParamProcessorFactory;
import com.aote.expression.unit.UnitProcessorFactory;
import java.util.Map;
import com.browsesoft.user.User;
import org.w3c.dom.Element;
}

class NumberExpression extends Parser;
{
    private double process(String param,Map attrs,User loginUser,HTMLBasicComponent component,Element config)
    {
        String str = ParamProcessorFactory.getInstance().process(param,attrs,loginUser,component,config);
        if(str == null || str.trim().equals("")) {
          str = "0";
        }
        return Double.parseDouble(str);
    }

	private String getParamString(String param) {
		int len = param.length();
		return param.substring(1,len - 1);
	}
}

expression [Map attrs,User loginUser,HTMLBasicComponent component,Element config]
 	returns [double result=0] {
	double b;
}
	: result=mulDiv[attrs,loginUser,component,config] ((ADD b=mulDiv[attrs,loginUser,component,config] {result += b;}) | (SUB b=mulDiv[attrs,loginUser,component,config] {result -= b;}))* 
	;

mulDiv [Map attrs,User loginUser,HTMLBasicComponent component,Element config]
 	returns [double result=0] {
	double b;
}
	: result=item[attrs,loginUser,component,config] ((MULT b=item[attrs,loginUser,component,config] {result *= b;}) | (DIV b=item[attrs,loginUser,component,config] {result = (b == 0 ? 0 : result / b);}))* 
	;

item [Map attrs,User loginUser,HTMLBasicComponent component,Element config]
 	returns [double result=0] {
}
	: (baseItem[attrs,loginUser,component,config] ID) => result=unitItem[attrs,loginUser,component,config]
	| result=baseItem[attrs,loginUser,component,config]
	;

unitItem [Map attrs,User loginUser,HTMLBasicComponent component,Element config]
	returns [double result=0]
	: result=baseItem[attrs,loginUser,component,config] (u:ID 
{
result=UnitProcessorFactory.getInstance().process(u.getText(), result);
}
	)
	;

baseItem [Map attrs,User loginUser,HTMLBasicComponent component,Element config]
 	returns [double result=0] {
	double b;
}	
	: v:NUMBER {result = Double.parseDouble(v.getText());} 
	| p:PARAMS {result = process(getParamString(p.getText()),attrs,loginUser,component,config);} 
	| LEFT b=expression[attrs,loginUser,component,config] RIGHT {result=b;}
	;

class BaseLexer extends Lexer;

WS: ' '
 	{$setType(Token.SKIP);} 
 	;
NUMBER: ('0'..'9')+(('.')('0'..'9')+)?
	;
	
ID
	: ('a'..'z'|'A'..'Z'|'\u0080'..'\ufffe')('a'..'z'|'A'..'Z'|'\u0080'..'\ufffe'|'0'..'9'|'_')*
	;
	
ADD: '+'
	;
SUB: '-'
	;
MULT: '*'
	;

PARAMS: '#' (~'#' | '\u0080'..'\ufffe')+ '#'
	;
DIV: '/'
	;
LEFT: "("
	;
RIGHT: ")"
	;
